"""
部署采购申请审批流程到 Flowable
"""
import sys
import os

# 添加父目录到路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from server.app.utils.flowable_client import FlowableClient
from server.config.config import Config
from server.app.app import create_app
from server.app.utils.process_definition_sync import parse_bpmn_process_tasks, sync_process_task_definitions

BPMN_FILENAME = 'purchase-approval.bpmn20.xml'
PROCESS_KEY = 'purchaseApproval'
DEPLOYMENT_NAME = '采购申请审批流程'

def deploy_purchase_approval_process():
    """部署采购申请审批流程"""
    print("=" * 60)
    print("部署采购申请审批流程到 Flowable")
    print("=" * 60)

    client = FlowableClient(
        base_url=Config.FLOWABLE_REST_URL,
        username=Config.FLOWABLE_REST_USER,
        password=Config.FLOWABLE_REST_PASSWORD
    )

    bpmn_file = os.path.join(
        os.path.dirname(__file__),
        'processes',
        BPMN_FILENAME
    )

    if not os.path.exists(bpmn_file):
        print(f"❌ 错误: BPMN 文件不存在: {bpmn_file}")
        return False

    try:
        print(f"\n📁 BPMN 文件: {bpmn_file}")
        print(f"🔗 Flowable URL: {Config.FLOWABLE_REST_URL}")
        print(f"👤 用户: {Config.FLOWABLE_REST_USER}")
        print("\n正在部署流程...")

        result = client.deploy_process(
            bpmn_file_path=bpmn_file,
            deployment_name=DEPLOYMENT_NAME
        )

        print("\n✅ 流程部署成功!")
        print(f"   部署 ID: {result.get('id')}")
        print(f"   部署名称: {result.get('name')}")
        print(f"   部署时间: {result.get('deploymentTime')}")

        deployment_id = result.get('id')
        process_definition_id = None
        if 'id' in result:
            # 查询刚部署的流程定义以获取 processDefinitionId
            definitions = client.get_process_definitions_by_deployment(deployment_id)
            if definitions:
                process_definition_id = definitions[0].get('id')
            print("\n📋 流程定义详情:")
            print(f"   流程定义 Key: {PROCESS_KEY}")
            print(f"   流程名称: {DEPLOYMENT_NAME}")
            print(f"   流程定义 ID: {process_definition_id}")

        # 解析 BPMN XML 并保存节点定义
        if deployment_id:
            try:
                with open(bpmn_file, 'r', encoding='utf-8') as fh:
                    xml_text = fh.read()
                definitions_by_key = parse_bpmn_process_tasks(xml_text)
                app = create_app()
                with app.app_context():
                    defs = client.get_process_definitions_by_deployment(deployment_id)
                    key_to_id = {d.get('key'): d.get('id') for d in defs if d.get('key') and d.get('id')}
                    saved = sync_process_task_definitions(definitions_by_key, key_to_id)
                    print(f"\n🗂 已保存流程节点定义 {saved} 条到数据库 (deployment_id={deployment_id})")
            except Exception as ex:
                print(f"⚠️  解析并保存流程节点定义失败: {ex}")

        print("\n" + "=" * 60)
        print("✨ 部署完成!")
        print("=" * 60)
        return True

    except Exception as e:
        print(f"\n❌ 部署失败: {str(e)}")
        import traceback
        traceback.print_exc()
        return False


def verify_deployment():
    """验证流程部署"""
    print("\n正在验证流程部署...")

    # 这里不强制使用客户端对象，直接使用 requests 进行验证

    try:
        import requests
        from requests.auth import HTTPBasicAuth

        url = f"{Config.FLOWABLE_REST_URL}/service/repository/process-definitions"
        params = {'key': PROCESS_KEY}

        response = requests.get(
            url,
            params=params,
            auth=HTTPBasicAuth(Config.FLOWABLE_REST_USER, Config.FLOWABLE_REST_PASSWORD)
        )

        if response.status_code == 200:
            data = response.json()
            if data.get('data'):
                process_def = data['data'][0]
                print("\n✅ 流程定义验证成功:")
                print(f"   流程 ID: {process_def.get('id')}")
                print(f"   流程 Key: {process_def.get('key')}")
                print(f"   版本: {process_def.get('version')}")
                print(f"   名称: {process_def.get('name')}")
                return True
            else:
                print("⚠️  未找到流程定义")
                return False
        else:
            print(f"⚠️  验证请求失败: {response.status_code}")
            return False
    except Exception as e:
        print(f"⚠️  验证过程出错: {str(e)}")
        return False


if __name__ == '__main__':
    success = deploy_purchase_approval_process()
    if success:
        verify_deployment()

        print("\n" + "=" * 60)
        print("📖 后续步骤:")
        print("=" * 60)
        print("1. 创建/确认用户组存在:")
        print("   - project_manager (项目经理)")
        print("   - purchase_dept (采购部)")
        print("   - finance_dept (财务部)")
        print("   - subsidiary_manager (子公司负责人)")
        print("")
        print("2. 启动 Python 后端服务器以提供相关业务接口:")
        print("   cd server")
        print("   python run.py")
        print("")
        print("3. 启动流程实例示例 (REST API):")
        print("   curl -X POST http://localhost:8000/api/purchase/apply \\")
        print("     -H \"Content-Type: application/json\" \\")
        print("     -d '{")
        print('       "applicant_id": "EMP001",')
        print('       "purchase_amount": 68000,')
        print('       "items": [{"name": "办公电脑", "qty": 4, "price": 8500}],')
        print('       "reason": "项目扩充设备采购"')
        print("     }'")
        print("=")
        print("4. 后续审批节点将根据 BPMN 流程中的候选组自动分配任务")
        print("")
        print("✨ 如果金额 > 50000，会自动进入子公司负责人审批节点")
        print("")
        print("⚠️ 注意: 服务任务 '生成采购单' 需要在 Flowable 引擎侧提供 Java Delegate 类: \n    com.flowable.service.GeneratePurchaseOrderService")
        print("   请确保该类已打包并部署到 Flowable 引擎运行环境，否则执行到该节点会失败。")
    else:
        print("\n❌ 部署失败，请检查 Flowable 服务、认证信息及 BPMN 文件路径。")
        sys.exit(1)
